home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.misc
- subject: v12i014: replacement ranlib for SCO Xenix
- from: Steve.Bleazard@robobar.co.uk
- Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
-
- Posting-number: Volume 12, Issue 14
- Submitted-by: Steve.Bleazard@robobar.co.uk
- Archive-name: ranlib/part01
-
- This is a replacement ranlib(CP) for SCO Xenix. It's needed when
- the library to be ranlib'ed has externals longer than 40 characters
- because the SCO ranlib barfs on them, although their ld(CP) appears
- to be quite happy with these long externals.
-
- This program was created with GCC and G++ users in mind. They should
- save this file if they see it posted.
-
- Freely redistributable, but copyrighted.
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # ranlib.c
- # This archive created: Wed Apr 25 15:04:27 1990
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'ranlib.c'" '(12748 characters)'
- if test -f 'ranlib.c'
- then
- echo shar: will not over-write existing file "'ranlib.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'ranlib.c'
- Xstatic char rcsid[] = "@(#)$Header: /pdsrc/Local/RCS/ranlib.c,v 1.3 90/04/24 14:05:00 root Exp $";
- X
- X/*
- X * (C) Copyright 1990 Stephen A. Bleazard <Steve@Robobar.Co.Uk>
- X *
- X * Permission is granted to redistribute this program and any derivatives
- X * thereof in source or binary form, for any purpose, including commercial
- X * use, provided that this copyright message is retained in the source code
- X * and is reproduced in full in any documentation that accompanies such
- X * redistribution. Source code redistribution is encouraged, but is not
- X * mandatory. The rcsid string above must be retained unmodified in any
- X * redistributed binary.
- X *
- X * NO WARRANTY: This software is licensed free of charge without any claim
- X * regarding its fitness for any purpose. The Licensor cannot accept
- X * responsibility for any damage arising from the use or inability to use
- X * this software for any purpose.
- X */
- X
- X/*
- X * This is a replacement ranlib(CP) for SCO Xenix 386 System V.
- X * I have only tested it on Xenix 2.3.2 with the 2.3 Development System:
- X * your mileage may vary.
- X *
- X * This replacement ranlib is required when either:
- X *
- X * a) you do not have a SCO Development system, but are hacking along
- X * with PD, free, and GNU development tools,
- X *
- X * or b) your library has external identifiers more than 40 characters
- X * long, which is not uncommon if you happen to be using g++,
- X * or indeed, most C++ compilers.
- X *
- X * Note that Xenix's ld seems perfectly happy to link objects with long
- X * identifiers, but the utilities like ranlib and nm barf on them under some
- X * circumstances which I am not going to bother to try to enumerate here
- X * or anywhere. ld -r does NOT cope with long identifiers. You Lose.
- X *
- X * CAVEAT: The Xenix struct ar_hdr as defined in /usr/include/ar.h depends
- X * upon a Microsoft specific bodge (#pragma pack(2)) to force alignment
- X * of a long on a 2 byte boundary. This is not a problem if you are
- X * compiling this ranlib with the Microsoft compiler. Those wishing
- X * to use my port of GCC to Xenix will require a version patched to understand
- X * #pragma pack(). Such version can be identified when
- X * $ /usr/local/lib/gcc-cc1 -version -quiet < /dev/null
- X * reports "#pragma pack() support included", which was not available with
- X * my original set of patches for GCC, and is in any case a non-compulsory
- X * compile-time option.
- X *
- X * Enjoy,
- X * Steve.
- X */
- X
- X/*
- X * $Log: ranlib.c,v $
- X * Revision 1.3 90/04/24 14:05:00 root
- X * Removed annoying ANSI prototypes.
- X * fixed array memname size
- X *
- X * Revision 1.2 90/04/23 07:56:07 root
- X * fixed argument to fseek at line 262.
- X * fixed -v message
- X *
- X * Revision 1.1 90/04/23 07:50:18 root
- X * Initial revision
- X *
- X */
- X
- X#include <stdio.h>
- X#include <varargs.h>
- X#include <string.h>
- X#include <ar.h>
- X
- Xtypedef struct symbol_t {
- X char *name;
- X long mempos;
- X struct symbol_t *next;
- X} Symbol;
- X
- X#undef i386
- X#define XARMAG 0177545
- X#define HDRSIZE 3
- X#define NOERROR 0
- X#define NODATA 1
- X#define ILLSTRLEN 2
- X#define EOFERR 3
- X#define OMFNAMELENGTH 127
- X#define MPUBDEF 0x90
- X#define MPUB386 0x91
- X
- X
- XFILE *objfile;
- Xint objerror = NOERROR;
- Xint verbose = 0; /* Say what we're doing */
- Xint trace = 0; /* Say EVERYTHING we're doing */
- Xlong ar_lib_start; /* where the actual lib stuff starts */
- XSymbol *symtable, *current_sym;
- X
- Xusage()
- X{
- X fprintf(stderr, "usage: ranlib [-v] [-t] archive...\n");
- X}
- X
- Xvoid vmsg(fmt, va_alist)
- Xchar *fmt;
- Xva_dcl
- X{
- X va_list args;
- X
- X va_start(args);
- X if (verbose)
- X vfprintf(stderr, fmt, args);
- X va_end(args);
- X}
- X
- Xvoid tmsg(fmt, va_alist)
- Xchar *fmt;
- Xva_dcl
- X{
- X va_list args;
- X
- X va_start(args);
- X if (trace)
- X vfprintf(stderr, fmt, args);
- X va_end(args);
- X}
- X
- X
- Xvoid error(fmt, va_alist)
- Xchar *fmt;
- Xva_dcl
- X{
- X va_list args;
- X
- X va_start(args);
- X fprintf(stderr, "error: ");
- X vfprintf(stderr, fmt, args);
- X va_end(args);
- X}
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X int opt;
- X extern optind;
- X
- X if (argc < 2)
- X {
- X usage();
- X exit(1);
- X }
- X
- X while ((opt = getopt(argc, argv, "vt")) != EOF)
- X {
- X switch (opt)
- X {
- X case 't':
- X trace = 1;
- X /*FALLTHROUGH*/
- X case 'v':
- X verbose = 1;
- X vmsg("ranlib version:\n %s\n", rcsid + 4);
- X vmsg("Please report bugs to steve@robobar.co.uk.\n");
- X break;
- X case '?':
- X usage();
- X exit(1);
- X break;
- X }
- X }
- X tmsg("Options selected: %s%s\n", trace ? "-t " : "",
- X verbose ? "-v " : "");
- X
- X for ( ; optind < argc; optind++ )
- X ranlib(argv[optind]);
- X exit(0);
- X}
- X
- Xint rdbytes(buff, count)
- Xchar *buff;
- Xint count;
- X{
- X int retval;
- X
- X if (retval = (fread(buff, 1, count, objfile) != count))
- X objerror = EOFERR;
- X return !retval;
- X}
- X
- Xint checkcnt(from, count)
- Xint *from, count;
- X{
- X if ((*from - 1) < count)
- X {
- X objerror = NODATA;
- X return 0;
- X }
- X *from -= count;
- X return 1;
- X}
- X
- X
- Xlong rdvint(count, reclen)
- Xint count;
- Xint *reclen;
- X{
- X long val = 0;
- X unsigned char b;
- X int i = 0;
- X
- X if (!checkcnt(reclen, count))
- X return -1;
- X while (i < count)
- X {
- X rdbytes(&b, 1);
- X val = val | ((long)b << ( 8 * i));
- X i++;
- X }
- X return val;
- X}
- X
- Xlong rdoffset(i386, reclen)
- Xint i386;
- Xint *reclen;
- X{
- X return rdvint(i386 ? 4 : 2, reclen);
- X}
- X
- Xunsigned int rdword(reclen)
- Xint *reclen;
- X{
- X return (unsigned int)rdvint(2, reclen);
- X}
- X
- Xunsigned char rdbyte(reclen)
- Xint *reclen;
- X{
- X unsigned char b;
- X
- X if (!checkcnt(reclen, 1))
- X return 0;
- X rdbytes(&b, 1);
- X return b;
- X}
- X
- Xunsigned int rdindex(reclen)
- Xint *reclen;
- X{
- X unsigned char b, b1;
- X
- X b = rdbyte(reclen);
- X if (b < 128)
- X return b;
- X b1 = rdbyte(reclen);
- X return (((unsigned int)b & 0x7f) << 8) + b1;
- X}
- X
- Xvoid rdomfstr(name, reclen)
- Xchar *name;
- Xint *reclen;
- X{
- X unsigned char l;
- X
- X l = rdbyte(reclen);
- X if (l > OMFNAMELENGTH)
- X {
- X name[0] = '\0';
- X objerror = ILLSTRLEN;
- X fseek(objfile, (long) *reclen, 1);
- X return;
- X }
- X if (!checkcnt(reclen, l))
- X {
- X name[0] = '\0';
- X return;
- X }
- X rdbytes(name, l); name[l] = '\0';
- X}
- X
- Xpubdef(i386, reclen, pos)
- Xint i386;
- Xint reclen;
- Xlong pos;
- X{
- X unsigned int grpindex, segindex, framenum;
- X
- X grpindex = rdindex(&reclen);
- X segindex = rdindex(&reclen);
- X if (grpindex == 0 && segindex == 0)
- X framenum = rdword(&reclen);
- X
- X while (reclen > 1)
- X {
- X char symbol_name[OMFNAMELENGTH+2];
- X unsigned long offset;
- X int type;
- X
- X rdomfstr(symbol_name, &reclen);
- X offset = rdoffset(i386, &reclen);
- X type = rdindex(&reclen);
- X
- X if (strncmp(symbol_name, " ", 2) == 0)
- X {
- X tmsg(" skipping %s @ %#x\n", symbol_name, pos);
- X }
- X else
- X {
- X
- X tmsg(" adding %s @ %#x\n", symbol_name, pos);
- X current_sym->next = (Symbol *)malloc(sizeof(Symbol));
- X current_sym = current_sym->next;
- X current_sym->name=(char *)malloc(strlen(symbol_name)+1);
- X strcpy(current_sym->name, symbol_name);
- X current_sym->mempos = pos;
- X }
- X }
- X fseek(objfile, (long)reclen, 1);
- X}
- X
- X
- Xreadsymbols(fp, pos, size)
- XFILE *fp;
- Xlong pos, size;
- X{
- X unsigned char buff[HDRSIZE+2];
- X unsigned int reclen, rectype;
- X long startpos;
- X long ftell();
- X
- X objfile = fp; startpos = ftell(fp); objerror = NOERROR;
- X
- X while (((ftell(fp) - startpos) < size) && rdbytes(buff, HDRSIZE))
- X {
- X int rectype, reclen;
- X
- X rectype = buff[0];
- X reclen = buff[1] | ((int)buff[2] << 8);
- X switch (rectype)
- X {
- X case MPUBDEF:
- X pubdef(0, reclen, pos);
- X break;
- X case MPUB386:
- X pubdef(1, reclen, pos);
- X break;
- X default:
- X fseek(objfile, (long)reclen, 1);
- X break;
- X }
- X
- X if (objerror != NOERROR)
- X {
- X error("invalid object file format\n");
- X return;
- X }
- X }
- X}
- X
- Xcopy_old_ar_to_new(oldar_fp, newar_fp)
- XFILE *oldar_fp, *newar_fp;
- X{
- X char buffer[BUFSIZ];
- X int size;
- X
- X fseek(oldar_fp, ar_lib_start, 0);
- X while ((size = fread(buffer, 1, BUFSIZ, oldar_fp)) != 0)
- X fwrite(buffer, 1, size, newar_fp);
- X}
- X
- Xtypedef Symbol *TablePtr;
- X
- Xstatic void merge(h1, t1, h2, t2, precedes)
- XTablePtr *h1, *t1, h2, t2;
- Xint (*precedes)();
- X{
- X TablePtr saveTail, lop, prevlop;
- X
- X
- X# define invert { TablePtr h;\
- X h = lop; lop = h2; h2 = h; h = *t1; *t1 = t2; t2 = h; }
- X
- X saveTail = t2->next; lop = *h1;
- X if ((*precedes)(h2, *h1))
- X {
- X invert
- X *h1 = lop;
- X }
- X while (lop != *t1)
- X {
- X prevlop = lop; lop = lop->next;
- X if ((*precedes)(h2, lop))
- X {
- X prevlop->next = h2;
- X invert
- X }
- X }
- X (*t1)->next = h2;
- X *t1 = t2;
- X t2->next = saveTail;
- X}
- X
- Xstatic void localsort(maxseqlen, head, tail, precedes)
- Xint maxseqlen;
- XTablePtr *head, *tail;
- Xint (*precedes)();
- X{
- X TablePtr nexthead, nexttail;
- X int length;
- X
- X length = 1; *tail = *head;
- X nexthead = (*tail)->next;
- X while ((length < maxseqlen) && (nexthead != (TablePtr)NULL))
- X {
- X localsort(length, &nexthead, &nexttail, precedes);
- X merge(head, tail, nexthead, nexttail, precedes);
- X nexthead = (*tail)->next;
- X length *= 2;
- X }
- X}
- X
- Xvoid chainsort(head, precedes)
- XTablePtr *head;
- Xint (*precedes)();
- X{
- X TablePtr finaltail;
- X
- X if ((*head)->next != (TablePtr)NULL)
- X localsort(0x7fff, head, &finaltail, precedes);
- X}
- X
- Xstatic int lesser(p1, p2)
- XTablePtr p1, p2;
- X{
- X return (strcmp(p1->name, p2->name) < 0);
- X}
- X
- Xwrite_new_ar(oldar_fp, name, symtable)
- XFILE *oldar_fp;
- Xchar *name;
- XSymbol *symtable;
- X{
- X static char template[] = "ranXXXXXX";
- X char *path;
- X Symbol *current;
- X unsigned short symbolCount;
- X long symtableSize, relocationFactor;
- X FILE *fp;
- X unsigned short magic = XARMAG;
- X struct ar_hdr sym_hdr;
- X long time();
- X long ftell();
- X
- X mktemp(template);
- X if (strchr(name, '/') != NULL) /* Has a path */
- X {
- X char *p, *tmpname;
- X
- X tmpname = (char *)malloc(strlen(name)+1);
- X strcpy(tmpname, name);
- X p = strrchr(tmpname, '/'); *p = '\0';
- X path = (char *)malloc(strlen(tmpname) + strlen(template) + 5);
- X sprintf(path, "%s/%s", tmpname, template);
- X free(tmpname);
- X }
- X else
- X {
- X path = (char *)malloc(strlen(template) + 5);
- X sprintf(path, "./%s", template);
- X }
- X tmsg("creating %s\n", path);
- X
- X chainsort(&symtable, lesser);
- X current = symtable; symbolCount = 0; symtableSize = 2;
- X while (current != NULL)
- X {
- X symtableSize += strlen(current->name) + 1 + 4;
- X symbolCount++;
- X tmsg("%s %#lx\n", current->name, current->mempos);
- X current = current->next;
- X }
- X relocationFactor = symtableSize + sizeof(struct ar_hdr);
- X if (relocationFactor & 1)
- X relocationFactor++;
- X relocationFactor -= ar_lib_start - 2;
- X tmsg("adding %d symbols, %#lx(%ld) bytes, ", symbolCount, symtableSize, symtableSize);
- X tmsg("relocation factor %#lx(%ld)\n", relocationFactor, relocationFactor);
- X
- X current = symtable;
- X while (current != NULL)
- X {
- X current->mempos += relocationFactor;
- X tmsg("%s %#lx\n", current->name, current->mempos);
- X current = current->next;
- X }
- X
- X if ((fp = fopen(path, "w")) == NULL)
- X {
- X fprintf(stderr,"ranlib: cannot open %s\n", path);
- X exit(1);
- X }
- X fwrite((void *)&magic, sizeof(unsigned short), 1, fp);
- X strncpy(sym_hdr.ar_name, "__.SYMDEF", 14);
- X sym_hdr.ar_date = time((long *)0);
- X sym_hdr.ar_uid = getuid();
- X sym_hdr.ar_gid = getgid();
- X sym_hdr.ar_mode = 0106644;
- X sym_hdr.ar_size = symtableSize;
- X fwrite((void *)&sym_hdr, sizeof(struct ar_hdr), 1, fp);
- X
- X fwrite((void *)&symbolCount, sizeof(unsigned short), 1, fp);
- X current = symtable;
- X while (current != NULL)
- X {
- X unsigned char len;
- X
- X len = (unsigned char)strlen(current->name);
- X fwrite((void *)&len, 1, 1, fp);
- X fwrite(current->name, len, 1, fp);
- X fwrite((void *)¤t->mempos, sizeof(long), 1, fp);
- X current = current->next;
- X }
- X
- X if (ftell(fp) & 1)
- X {
- X char nl = 0;
- X
- X fwrite(&nl, 1, 1, fp);
- X }
- X copy_old_ar_to_new(oldar_fp, fp);
- X fclose(fp);
- X
- X unlink(name);
- X link(path, name);
- X unlink(path);
- X}
- X
- Xranlib(name)
- Xchar *name;
- X{
- X FILE *fp;
- X struct ar_hdr hdr;
- X unsigned short magic = 0;
- X long memoffset, ftell();
- X int memcount;
- X
- X if ((fp = fopen(name, "r")) == NULL)
- X {
- X fprintf(stderr,"ranlib: cannot open %s\n", name);
- X exit(1);
- X }
- X vmsg("processing %s...", name);
- X tmsg("\n");
- X
- X if ((fread((void *)&magic, sizeof(unsigned short), 1, fp) != 1) ||
- X (magic != XARMAG))
- X {
- X error("%s not in archive format\n", name);
- X return;
- X }
- X
- X symtable = current_sym = (Symbol *)malloc(sizeof(Symbol));
- X memoffset = ftell(fp); memcount = 0; ar_lib_start = 2;
- X
- X while (fread((void *)&hdr, sizeof(struct ar_hdr), 1, fp) == 1)
- X {
- X char memname[15];
- X
- X memname[14] = '\0'; strncpy(memname, hdr.ar_name, 14);
- X vmsg("%s ", memname);
- X tmsg("(pos = %#x, size = %ld)\n", memoffset, hdr.ar_size);
- X if ((strcmp(memname, "__.SYMDEF") == 0) && !memcount)
- X {
- X ar_lib_start = memoffset + sizeof(struct ar_hdr)
- X + hdr.ar_size;
- X if (ar_lib_start & 1)
- X ar_lib_start++;
- X tmsg("%s ", memname);
- X vmsg("(skipped) ");
- X tmsg("\n");
- X }
- X else
- X readsymbols(fp, memoffset, hdr.ar_size);
- X
- X memcount++;
- X memoffset += sizeof(struct ar_hdr) + hdr.ar_size;
- X if (memoffset & 1) memoffset++;
- X fseek(fp, memoffset, 0);
- X }
- X current_sym->next = NULL;
- X current_sym = symtable; symtable = symtable->next; free(current_sym);
- X
- X write_new_ar(fp, name, symtable);
- X fclose(fp);
- X
- X for (current_sym = symtable; current_sym != NULL;)
- X {
- X Symbol *refuse;
- X
- X refuse = current_sym; current_sym = current_sym->next;
- X free(refuse);
- X }
- X vmsg("\n");
- X}
- SHAR_EOF
- if test 12748 -ne "`wc -c < 'ranlib.c'`"
- then
- echo shar: error transmitting "'ranlib.c'" '(should have been 12748 characters)'
- fi
- fi # end of overwriting check
- # End of shell archive
- exit 0
-
-